#include "StdAfx.h"
#include "RegFormat.h"

RegFormat::RegFormat(void)
{
}

RegFormat::~RegFormat(void)
{
}

/*static*/ bool RegFormat::TextToKeyName(CString text,RegKey& key)
{
	int len = text.GetLength();
	if (text[0]!=_T('[') || text[len-1]!=_T(']'))
		return false;
	key.SetName(text.Mid(1,len-2));
	return true;
}

/*static*/ bool RegFormat::KeyNameToText(RegKey key, CString& text)
{
	text.Format(_T("[%s]"),key.GetName());
	return true;
}

/*static*/ bool RegFormat::TextToValue(CString text,RegKeyValue& keyValue)
{
	int len = text.GetLength();
	if (len <= 0)
		return false;
	if (text[0] != _T('\"'))
		return false;
	int keyLen = text.Find(_T('\"'),1);
	int equalIndex = keyLen + 1; 
	if (keyLen == -1 ||
		equalIndex >len ||
		text[equalIndex] != _T('='))
		return false;
	keyValue.SetName(text.Mid(1,keyLen-1));
	return SetValueTypeAndData(text.Mid(equalIndex+1),keyValue);
}
/*static*/ bool RegFormat::SetValueTypeAndData(CString text,RegKeyValue& keyValue)
{
	if (0 == text.Find(TEXT_HEX))
	{
		keyValue.SetType(RegTextType_Binary);
		keyValue.SetData(text.Mid(TEXT_HEX_SIZE));
		return true;
	}
	else if (0 == text.Find(TEXT_DWORD))
	{
		keyValue.SetType(RegTextType_DWORD);
		keyValue.SetData(text.Mid(TEXT_DWORD_SIZE));
		return true;
	}
	else if (QUOTATION_MARK == text[0] && QUOTATION_MARK == text[text.GetLength()-1])
	{
		keyValue.SetType(RegTextType_String);
		keyValue.SetData(text.Mid(1,text.GetLength()-2));
		return true;
	}
	return false;
}


/*static*/ bool RegFormat::ValueToText(RegKeyValue keyValue,CString& text)
{
	switch(keyValue.GetType())
	{
	case RegTextType_DWORD:
		text.Format(_T("\"%s\"=%s%s"),keyValue.GetName(),TEXT_DWORD,keyValue.GetData());
		return true;
	case RegTextType_Binary:
		text.Format(_T("\"%s\"=%s%s"),keyValue.GetName(),TEXT_HEX,keyValue.GetData());
		return true;
	case RegTextType_String:
		text.Format(_T("\"%s\"=%c%s%c"),keyValue.GetName(),QUOTATION_MARK,keyValue.GetData(),QUOTATION_MARK);
		return true;
	}
	return false;
}

/*static*/ bool RegFormat::ValueDataToDWORD(RegKeyValue keyValue,DWORD& data)
{
	if (keyValue.GetType() != RegTextType_DWORD)
		return false;
	data = HexTextToDWORD(keyValue.GetData());
	return true;
}

/*static*/ bool RegFormat::DWORDToValueData(DWORD data, RegKeyValue& keyValue)
{
	if (keyValue.GetType() != RegTextType_DWORD)
		return false;
	CString str;
	str.Format(_T("%08x"),data);
	keyValue.SetData(str);
	return true;
}

/*static*/ bool RegFormat::ValueDataToBinary(RegKeyValue regKeyValue, BYTE* data, size_t dataLen, size_t& realLen)
{
	if (regKeyValue.GetType() != RegTextType_Binary)
		return false;

	CString valueData = regKeyValue.GetData();
	realLen = valueData.GetLength()/3+1;

	size_t useLen = min(dataLen,realLen);

	int step = 3;
	for (size_t i=0;i<useLen;++i)
	{
		data[i] = HexTextToBYTE(&(valueData.GetBuffer())[step*i]);
	}
	return true;
}

/*static*/ bool RegFormat::BinaryToValueData(const BYTE* data, size_t len, RegKeyValue& regKeyValue)
{
	if (regKeyValue.GetType() != RegTextType_Binary)
		return false;
	CString out(_T('\0'),len*3-1);
	CString strTmp;
	for (size_t i=0;i<len;++i)
	{
		strTmp.Format(_T("%02x "),data[i]);
		out.SetAt(i*3,strTmp[0]);
		out.SetAt(i*3+1,strTmp[1]);
		if (i < len-1)
			out.SetAt(i*3+2,strTmp[2]);
	}
	regKeyValue.SetData(out);
	return true;
}

/*static*/ bool RegFormat::ValueDataToString(RegKeyValue regKeyValue, CString& data)
{
	if (regKeyValue.GetType() != RegTextType_String)
		return false;
	data = regKeyValue.GetData();
	return true;
}

/*static*/ bool RegFormat::StringToValueData(CString data, RegKeyValue& regKeyValue)
{
	if (regKeyValue.GetType() != RegTextType_String)
		return false;
	regKeyValue.SetData(data);
	return true;
}

/*static*/ bool RegFormat::IsKey(CString text)
{
	if (text[0] == _T('[') &&
		text[text.GetLength()-1] == _T(']'))
		return true;
	return false;
}

/*static*/ bool RegFormat::IsValue(CString text)
{
	int len = text.GetLength();
	if (len <= 0)
		return false;
	if (text[0] != _T('\"'))
		return false;
	int keyLen = text.Find(_T('\"'),1);
	int equalIndex = keyLen + 1; 
	if (keyLen == -1 ||
		equalIndex >len ||
		text[equalIndex] != _T('='))
		return false;
	return true;
}